package work

import (
	"github.com/subosito/gotenv"
	"goskeleton/app/global/variable"
	"goskeleton/app/model"
	"goskeleton/app/utils/data_bind"
	"os"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

func init() {
	// 确保.env文件中的环境变量被加载
	gotenv.Load()
}

func CreateWorkFactory(sqlType string) *WorkModel {
	return &WorkModel{BaseModel: model.BaseModel{DB: model.UseDbConn(sqlType)}}
}

type WorkModel struct {
	model.BaseModel
	Type               int    `gorm:"column:type" json:"type" binding:"min=0"`               // 工作类型
	ProjectId          int    `gorm:"column:project_id" json:"project_id" binding:"min=0"`      // 项目ID
	RequirementContent string `gorm:"column:requirement_content" json:"requirement_content"`        // 需求内容
	ContactPersonId    int    `gorm:"column:contact_person_id" json:"contact_person_id"`            // 对接人
	Price              string `gorm:"column:price" json:"price"`                                   // 价格（decimal类型用string处理）
	SettlementStatus   int    `gorm:"column:settlement_status" json:"settlement_status"`            // 结算状态
	SettlementMethod   int    `gorm:"column:settlement_method" json:"settlement_method"`            // 结算方式
	PaymentMethod      int    `gorm:"column:payment_method" json:"payment_method"`                 // 支付方式
	InvoiceStatus      int    `gorm:"column:invoice_status" json:"invoice_status"`                 // 发票状态
	SettlementDate     string `gorm:"column:settlement_date" json:"settlement_date"`               // 结算日期
	InvoiceDate        string `gorm:"column:invoice_date" json:"invoice_date" binding:"omitempty"`                    // 开票日期
	PaymentDate        string `gorm:"column:payment_date" json:"payment_date" binding:"omitempty"`                    // 支付日期
	CreatedAt          string `gorm:"column:created_at" json:"created_at"`                        // 创建时间
	UpdatedAt          string `gorm:"column:updated_at" json:"updated_at"`                        // 更新时间
	ContactPersonName  string `gorm:"-" json:"contact_person_name"`
	ProjectName        string `gorm:"-" json:"project_name"`
	DeleteStatus       int    `gorm:"column:delete_status" json:"delete_status"` // 是否删除 1否 2是
	DetailImg          string `gorm:"column:detail_img" json:"detail_img"` //详情图片
}

// TableName sets the name of the table in the database
func (w *WorkModel) TableName() string {
	return "tb_work"
}

func (w *WorkModel) InsertData(c *gin.Context) bool {
	var tmp WorkModel
	if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil {
		// 构建要插入的字段列表，排除空值的日期字段
		fields := []string{"type", "project_id", "requirement_content", "contact_person_id", "price", 
			"settlement_status", "settlement_method", "payment_method", "invoice_status", "settlement_date",
			"created_at", "updated_at"}
		
		// 只有当日期字段不为空时才添加到插入字段列表
		if tmp.InvoiceDate != "" {
			fields = append(fields, "invoice_date")
		}
		if tmp.PaymentDate != "" {
			fields = append(fields, "payment_date")
		}
		if tmp.DetailImg != "" {
			fields = append(fields, "detail_img")
			tmp.DetailImg = os.Getenv("APP_URL") + tmp.DetailImg
		}
	

		// 使用Select指定要插入的字段
		if res := w.Select(fields).Create(&tmp); res.Error == nil {
			return true
		} else {
			variable.ZapLog.Error("WorkModel 数据新增出错", zap.Error(res.Error))
		}
	} else {
		variable.ZapLog.Error("WorkModel 数据绑定出错", zap.Error(err))
	}
	return false
}

// 根据关键词查询用户表的条数
func (w *WorkModel) getCounts() (counts int64) {
	sql := "select  count(*) as counts from tb_work"
	if _ = w.Raw(sql).First(&counts); counts > 0 {
		return counts
	} else {
		return 0
	}
}

func (w *WorkModel) GetWorkCountByWhere(
	settlementStatus,
	settlementMethod,
	paymentMethod,
	invoiceStatus int,
	settlementDateStart,
	settlementDateEnd,
	invoiceDateStart,
	invoiceDateEnd,
	paymentDateStart,
	paymentDateEnd string,
	departmentEmployeeIds []int,
) (counts int64) {
	query := w.Model(w)
	if settlementStatus > 0 {
		query = query.Where("settlement_status = ?", settlementStatus)
	}
	if len(departmentEmployeeIds) > 0 {
		query = query.Where("contact_person_id in (?)", departmentEmployeeIds)
	}
	if settlementMethod > 0 {
		query = query.Where("settlement_method = ?", settlementMethod)
	}
	if paymentMethod > 0 {
		query = query.Where("payment_method = ?", paymentMethod)
	}
	if invoiceStatus > 0 {
		query = query.Where("invoice_status = ?", invoiceStatus)
	}
	if settlementDateStart != "" {
		query = query.Where("settlement_date >= ?", settlementDateStart)
	}
	if settlementDateEnd != "" {
		query = query.Where("settlement_date <= ?", settlementDateEnd)
	}
	if invoiceDateStart != "" {
		query = query.Where("invoice_date >= ?", invoiceDateStart)
	}
	if invoiceDateEnd != "" {
		query = query.Where("invoice_date <= ?", invoiceDateEnd)
	}
	if paymentDateStart != "" {
		query = query.Where("payment_date >= ?", paymentDateStart)
	}
	if paymentDateEnd != "" {
		query = query.Where("payment_date <= ?", paymentDateEnd)
	}
	query = query.Where("delete_status = ?", 1)
	if err := query.Count(&counts).Error; err != nil {
		variable.ZapLog.Error("WorkModel 数据查询出错", zap.Error(err))
	}else{
		return counts
	}
	return 0
}

func (w *WorkModel) UpdateData(c *gin.Context) bool {
	var tmp WorkModel
	if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil {
		// 构建需要更新的字段列表，处理日期字段空值问题
		fields := []string{"created_at", "updated_at", "type", "project_id", "requirement_content", "contact_person_id", "price", "settlement_status", "settlement_method", "payment_method", "invoice_status", "settlement_date"}
		
		// 只有当日期字段不为空时才添加到更新列表
		if tmp.InvoiceDate != "" {
			fields = append(fields, "invoice_date")
		}
		if tmp.PaymentDate != "" {
			fields = append(fields, "payment_date")
		}
		if tmp.DetailImg != "" {
			fields = append(fields, "detail_img")
			tmp.DetailImg = os.Getenv("APP_URL") + tmp.DetailImg
		}
		
		// 使用Select方法指定只更新非空的日期字段
		if res := w.Select(fields).Save(&tmp); res.Error == nil {
			return true
		} else {
			variable.ZapLog.Error("WorkModel 数据更新出错", zap.Error(res.Error))
			return false

		}
	} else {
		variable.ZapLog.Error("WorkModel 数据更新，参数解析绑定失败", zap.Error(err))
		return false
	}
}

func (w *WorkModel) ListData(
	page, limitItems int,
	order string,
	settlementStatus,
	settlementMethod,
	paymentMethod,
	invoiceStatus int,
	settlementDateStart,
	settlementDateEnd,
	invoiceDateStart,
	invoiceDateEnd,
	paymentDateStart,
	paymentDateEnd string,
	departmentEmployeeIds []int,
) (totalCounts int64, tmp []*WorkModel) {
	// var tmp []*WorkModel
	counts := w.GetWorkCountByWhere(
		settlementStatus,
		settlementMethod,
		paymentMethod,
		invoiceStatus,
		settlementDateStart,
		settlementDateEnd,
		invoiceDateStart,
		invoiceDateEnd,
		paymentDateStart,
		paymentDateEnd,
		departmentEmployeeIds,
	)
	if counts == 0 {
		return 0, nil
	}

	query := w.Model(w)
	if settlementStatus > 0 {
		query = query.Where("settlement_status = ?", settlementStatus)
	}
	if len(departmentEmployeeIds) > 0 { 
		query = query.Where("contact_person_id in (?)", departmentEmployeeIds)
	}
	if settlementMethod > 0 {
		query = query.Where("settlement_method = ?", settlementMethod)
	}
	if paymentMethod > 0 {
		query = query.Where("payment_method = ?", paymentMethod)
	}
	if invoiceStatus > 0 {
		query = query.Where("invoice_status = ?", invoiceStatus)
	}
	if settlementDateStart != "" {
		query = query.Where("settlement_date >= ?", settlementDateStart)
	}
	if settlementDateEnd != "" {
		query = query.Where("settlement_date <= ?", settlementDateEnd)
	}
	if invoiceDateStart != "" {
		query = query.Where("invoice_date >= ?", invoiceDateStart)
	}
	if invoiceDateEnd != "" {
		query = query.Where("invoice_date <= ?", invoiceDateEnd)
	}
	if paymentDateStart != "" {
		query = query.Where("payment_date >= ?", paymentDateStart)
	}
	if paymentDateEnd != "" {
		query = query.Where("payment_date <= ?", paymentDateEnd)
	}
	query = query.Where("delete_status = ?", 1)

	if res := query.Limit(limitItems).Offset(page).Order(order).Find(&tmp); res.Error == nil {

		return counts, tmp

	} else {
		variable.ZapLog.Error("WorkModel 数据查询出错", zap.Error(res.Error))
	}
	return 0, nil
}

func (w *WorkModel) ShowOneItem(id int) (tmp *WorkModel) {
	if res := w.Where("id = ?", id).First(&tmp); res.Error == nil && tmp.Id > 0 {
	
		return tmp
	} else {
		variable.ZapLog.Error("WorkModel 数据查询出错", zap.Error(res.Error))
	}
	return nil

}

func (w *WorkModel) GetWorkByIds(ids []int) (tmp []*WorkModel) {
	if res := w.Where("id in (?)", ids).Where("delete_status = ?", 1).Find(&tmp); res.Error == nil {
		return tmp
	}
	return nil
}

func (w *WorkModel) TotalStatistics() (totalStatistics *TotalStatistics) {
	totalStatistics = &TotalStatistics{}
	var tmp []*TotalStatisticsPriceBySettlement
	query := w.Model(w)
	query.Select("settlement_status, sum(price) as total_price")
	query.Where("delete_status = ?", 1)
	query.Group("settlement_status")
	if err := query.Find(&tmp).Error; err != nil {
		variable.ZapLog.Error("WorkModel 数据查询出错", zap.Error(err))
	}
	if len(tmp) > 0 {
		for _,v := range tmp {
			if v.SettlementStatus == 1 {
				totalStatistics.Settled = v.TotalPrice
			}
			if v.SettlementStatus == 2 {
				totalStatistics.Unsettled = v.TotalPrice
			}
			totalStatistics.TotalPrice += v.TotalPrice
		}
	}
	return totalStatistics
}

func (w *WorkModel) DeleteData(id int) bool {
	if res := w.Model(w).Where("id = ?", id).Updates(map[string]interface{}{"delete_status": 2}); res.Error == nil {
		return true
	} else {
		variable.ZapLog.Error("WorkModel DeleteData 数据更新出错", zap.Int("id", id), zap.Error(res.Error))
	}
	return false
}
